package client;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import javax.swing.Timer;
import javax.swing.JOptionPane;

/**
 *
 * @author hxl851
 */
public class Client {

    public static final int PORT = 8888;
    public static final int DELAY = 40;
    private Socket socket;
    private int id;
    private JoinGameFrame joinGameFrame;
    private GameFrame gameFrame;
    private Timer recievingTimer;
    private ObjectInputStream inObj;
    private ObjectOutputStream outObj;

    //This constructor is called by Server player
    public Client(String ip) throws UnknownHostException, IOException {
        socket = new Socket(ip, PORT);
        joinGameFrame = null;
        Thread t = new Thread(new Waiting());
        t.start();
    }

    //This constructor is called by Client player
    public Client(String ip, JoinGameFrame joinGameFrame) throws UnknownHostException, IOException {
        socket = new Socket(ip, PORT);
        this.joinGameFrame = joinGameFrame;
        this.joinGameFrame.setStatus();
        Thread t = new Thread(new Waiting());
        t.start();
    }

    //Send request to server
    public void send(String msg) throws IOException {
        outObj.writeObject(msg);
    }

    public void setID(int id) {
        this.id = id;
    }

    public int getID() {
        return id;
    }

    public GameFrame getGameFrame() {
        return gameFrame;
    }

    //Wait for game beginning
    private void waiting() throws IOException, ClassNotFoundException {
        inObj = new ObjectInputStream(socket.getInputStream());
        String status = (String) inObj.readObject();
        if (status.equals("start")) {
            //Game begins
            if (joinGameFrame != null) {
                joinGameFrame.dispose();
            }
            gameFrame = new GameFrame(this);
            outObj = new ObjectOutputStream(socket.getOutputStream());

            //Start to keep recieving data from server
            recievingTimer = new Timer(DELAY, new Recieving());
            recievingTimer.start();
        } else {
            JOptionPane.showMessageDialog(null, "Network connecting failed.");
            System.exit(1);
        }
    }

    //Thread used to wait for game beginning
    class Waiting implements Runnable {

        public void run() {
            try {
                waiting();
            } catch (Exception ex) {
                ex.printStackTrace();
                JOptionPane.showMessageDialog(null, "Network connecting failed.");
                System.exit(1);
            }
        }
    }

    //Timer calls this listener to keep recieving data from server
    class Recieving implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            try {
                Object obj = inObj.readObject();
                if (obj instanceof ArrayList) {
                    gameFrame.gameUpdate((ArrayList) obj);
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                JOptionPane.showMessageDialog(gameFrame, ex.getMessage());
                System.exit(1);
            }
        }
    }
}
